#region Using Statements
using System;
using System.IO;
using System.Xml;
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion

namespace SkyBurner.Screens
{
    class SkyBurnerScreenLevelChooser : SkyBurnerScreenBase
    {
        #region SkyBurnerLevel class
        private class SkyBurnerLevel : BaseDrawableObject
        {
            private String m_planetName;
            public String Name
            {
                get { return m_planetName; }
            }

            private String m_planetDescription;
            public String Description
            {
                get { return m_planetDescription; }
            }

            private String m_planetLevelFile;
            public String LevelFile
            {
                get { return m_planetLevelFile; }
            }

            private MOODModel m_planetModel;
            private MOODBlinnPhongShader m_moodBlinnPhongShader;
            private Vector3 m_vLightPosition = new Vector3(10.0f, 30.0f, -30.0f);

            public SkyBurnerLevel(BaseGame game, XmlNode xmlLevelNode)
                : base(game)
            {
                m_planetName = xmlLevelNode.SelectSingleNode("Name").InnerText;
                m_planetDescription = xmlLevelNode.SelectSingleNode("Description").InnerText;
                m_planetLevelFile = xmlLevelNode.SelectSingleNode("LevelFile").InnerText;

                String planetModel = xmlLevelNode.SelectSingleNode("Model").InnerText;

                m_planetModel = new MOODModel(game, planetModel);
                m_moodBlinnPhongShader = (MOODBlinnPhongShader)m_Game.ShadersManager.GetShader("BlinnPhongShader");

                m_customEffect = game.ContentManager.Load<Effect>("Data\\Shaders\\SkyBurnerStarFighter");
                
                m_vLightDirection = new Vector3(0.4f, 0.4f, -1.0f);
                m_vLightAmbient = new Vector4(0.3f, 0.3f, 0.4f, 1.0f);
                m_vLightDiffuse = new Vector4(0.9f, 1.0f, 1.0f, 1.0f);
                m_vLightSpecular = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
            }

            public override void Update(GameTime gameTime, Camera pActiveCamera)
            {
                m_planetModel.WorldMatrix = Matrix.CreateRotationY((float)gameTime.TotalGameTime.TotalSeconds) * Matrix.CreateTranslation(0.0f, 10.0f, 0.0f);
                m_planetModel.ViewMatrix = Matrix.CreateLookAt(pActiveCamera.Position, pActiveCamera.LookAt, pActiveCamera.Up);
                m_planetModel.ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(pActiveCamera.FOV, pActiveCamera.AspectRatio, pActiveCamera.NearPlane, pActiveCamera.FarPlane);
            }

            public override void Draw(GameTime gameTime, Camera pActiveCamera)
            {
                m_Game.GraphicsDevice.RenderState.CullMode = CullMode.None;
                m_Game.GraphicsDevice.RenderState.DepthBufferEnable = true;
                m_Game.GraphicsDevice.RenderState.AlphaBlendEnable = false;
                m_Game.GraphicsDevice.RenderState.AlphaTestEnable = false;

                m_moodBlinnPhongShader.Draw(gameTime, pActiveCamera, pActiveCamera.Position, m_vLightPosition, m_planetModel);
            }
        }
        #endregion

        private Camera m_cameraMenu;
        private Collection<SkyBurnerLevel> m_levelList = new Collection<SkyBurnerLevel>();
        private int m_nSelectedLevelIndex = 0;

        public SkyBurnerScreenLevelChooser(BaseGame game, ScreenManager pScreenManager, int nScreenID, bool bActive)
            : base(game, pScreenManager, nScreenID, bActive)
        {
            // setup camera menu...
            m_cameraMenu = new Camera(game);

            m_cameraMenu.Position = new Vector3(0.0f, 0.0f, -50.0f);
            m_cameraMenu.Up = new Vector3(0.0f, 1.0f, 0.0f);
            m_cameraMenu.View = new Vector3(0.0f, 0.0f, 1.0f);
            m_cameraMenu.NearPlane = 0.1f;
            m_cameraMenu.FarPlane = 1500.0f;
            m_cameraMenu.FOV = MathHelper.PiOver2;
            m_cameraMenu.AspectRatio = (float)m_Game.GraphicsDevice.Viewport.Width / m_Game.GraphicsDevice.Viewport.Height;
            
            // load planets...
            XmlDocument xmlLevels = new XmlDocument();
            try
            {
                xmlLevels.Load("Data\\Levels\\Levels.xml");

                XmlNode xmlRootNode = xmlLevels.DocumentElement;
                foreach (XmlNode xmlLevelNode in xmlRootNode.ChildNodes)
                    m_levelList.Add(new SkyBurnerLevel(m_Game, xmlLevelNode));
            }
            catch (XmlException e)
            {
                m_Game.Console.Print("SkyBurnerScreenLevelChooser.Ctor : " + e.Message);
            }

            m_nSelectedLevelIndex = 0;
        }

        public override void Activate()
        {
            base.Activate();

            m_nSelectedLevelIndex = 0;
        }

        public override void Update(GameTime gameTime, Camera pActiveCamera)
        {
            base.Update(gameTime, pActiveCamera);

            if (m_Game.UserInputState.IsUserAction(UserAction.Right))
            {
                m_nSelectedLevelIndex++;
                m_Game.SoundManager.PlaySound("Click");
            }
            else if (m_Game.UserInputState.IsUserAction(UserAction.Left))
            {
                m_nSelectedLevelIndex--;
                m_Game.SoundManager.PlaySound("Click");
            }
            else if (m_Game.UserInputState.IsUserAction(UserAction.Back))
            {
                m_Game.SoundManager.PlaySound("Highlight");
                m_screenManager.ActivateScreen(SkyBurnerScreenID.sbs_Main);
            }

            if (m_Game.UserInputState.IsUserAction(UserAction.ButtonA))
            {
                if (File.Exists(m_levelList[m_nSelectedLevelIndex].LevelFile))
                {
                    SkyBurnerScreenInGame inGameScreen = (SkyBurnerScreenInGame)m_screenManager.GetScreen(SkyBurnerScreenID.sbs_Game);

                    m_Game.SoundManager.PlaySound("Highlight");

                    inGameScreen.GameLevelFile = m_levelList[m_nSelectedLevelIndex].LevelFile;
                    m_screenManager.ActivateScreen(SkyBurnerScreenID.sbs_Game);
                }
            }
            else
            {
                m_nSelectedLevelIndex = Math.Abs(m_nSelectedLevelIndex) % m_levelList.Count;
                m_levelList[m_nSelectedLevelIndex].Update(gameTime, m_cameraMenu);
            }
        }

        public override void Draw(GameTime gameTime, Camera pActiveCamera)
        {
            // base.Draw(gameTime);
            m_Game.GraphicsDevice.Clear(Color.Black);

            m_levelList[m_nSelectedLevelIndex].Draw(gameTime, m_cameraMenu);
            if ( !File.Exists(m_levelList[m_nSelectedLevelIndex].LevelFile) )
                m_Game.BitmapFont.PrintCenterX(200, "Not Available", 32);

            m_Game.BitmapFont.PrintCenterX(10, m_levelList[m_nSelectedLevelIndex].Name, 32);
            m_Game.BitmapFont.PrintCenterX(400, m_levelList[m_nSelectedLevelIndex].Description, 16);
        }
    }
}
